package controllers

import (
	"cms/libs"
	"cms/model"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/kataras/iris"
	"github.com/kataras/iris/mvc"
	"github.com/kataras/iris/sessions"
	config "github.com/spf13/viper"
	"github.com/yunge/sphinx"
	"html/template"
	"math"
	"strconv"
	"strings"
	"time"
)

type IndexController struct {
	Ctx     iris.Context
	Session *sessions.Session
	Apply   model.Apply
}

func (c *IndexController) CommonData() map[string]interface{} {
	data := make(map[string]interface{})
	navModel := model.Nav{}

	//系统设置
	settingModel := model.Setting{}
	settingMap := make(map[string]string)
	for _, v := range settingModel.ListAll() {
		settingMap[v.Key] = v.Val
	}
	data["setting"] = settingMap
	data["HotSearch"] = strings.Split(settingMap["HotSearch"], ",")
	//推荐位
	recommendModel := model.Recommend{}
	recommendMap := make(map[string]interface{})
	for _, v := range recommendModel.ListAll() {
		recommendMap[v.Key] = navModel.ListRecommend(int(v.ID))
	}
	data["recommend"] = recommendMap
	//友情链接
	linkModel := model.Link{}
	link := linkModel.ListAll()
	data["link"] = link
	//最近更新20条记录，分类不为空
	data["news"] = navModel.ListNews()
	//类别浮窗
	category := model.Category{}
	parentList := category.ListByPid(0)
	data["parentList"] = parentList
	return data
}

func (c *IndexController) Get() mvc.View {
	cacheKey := "index"
	templatePath := "pc"
	if c.Ctx.IsMobile() {
		templatePath = "mobile"
	}

	if v, rs := libs.GetCache(cacheKey); rs {
		return mvc.View{
			Name:   "www/" + templatePath + "/index.html",
			Layout: "www/" + templatePath + "/shared/layoutFront.html",
			Data: iris.Map{
				"data": v,
			},
		}
	}

	data := c.CommonData()
	//分类数据
	navModel := model.Nav{}
	category := model.Category{}
	setting := model.Setting{}
	list := make(map[model.Category][]model.Category)
	parentList := category.ListByPid(0)
	for _, v := range parentList {
		childList := category.ListByPid(int(v.ID))
		for key, val := range childList {
			childList[key].Navs = navModel.ListCate(int(val.ID))
		}
		list[v] = childList
	}
	data["list"] = list
	libs.SetCacheDefault(cacheKey, data, time.Duration(setting.CacheTime())*time.Second)

	return mvc.View{
		Name:   "www/" + templatePath + "/index.html",
		Layout: "www/" + templatePath + "/shared/layoutFront.html",
		Data: iris.Map{
			"data": data,
		},
	}
}

func (c *IndexController) GetApply() mvc.View {
	data := c.CommonData()

	Category := model.Category{}
	CateList := Category.List()
	model.ListTree = []model.Category{}
	CateList = Category.GetTree(CateList, 0, 0)

	templatePath := "pc"
	if c.Ctx.IsMobile() {
		templatePath = "mobile"
	}
	return mvc.View{
		Name:   "www/" + templatePath + "/apply.html",
		Layout: "www/" + templatePath + "/shared/layoutFront.html",
		Data: iris.Map{
			"Title":    "申请",
			"data":     data,
			"CateList": CateList,
		},
	}
}

func (c *IndexController) PostApply() {
	captcha := c.Ctx.PostValueDefault("captcha", "")
	if captcha == "" {
		_, _ = c.Ctx.JSON(iris.Map{"status": "error", "data": "验证码必填"})
		return
	}

	sessionCaptcha := c.Session.GetString("CaptchaKey")
	if !libs.VerifyCaptcha(sessionCaptcha, captcha) {
		_, _ = c.Ctx.JSON(iris.Map{"status": "error", "data": "验证码错误"})
		return
	}

	if err := c.Apply.AddApply(c.Ctx.FormValues()); err == nil {
		_, _ = c.Ctx.JSON(iris.Map{"status": "success", "data": ""})
	} else {
		_, _ = c.Ctx.JSON(iris.Map{"status": "error", "data": err.Error()})
	}
}

func (c *IndexController) GetCateBy(cid int) mvc.View {
	page, err := strconv.Atoi(c.Ctx.URLParam("page"))
	if err != nil || page < 1 {
		page = 1
	}

	Nav := model.Nav{}
	data := c.CommonData()

	list, totalCount, totalPages := Nav.ListCatePage(page, cid)
	Category := model.Category{}
	Cate, _ := Category.CategoryInfo(uint(cid))

	//重写title keyword desc
	settingModel := model.Setting{}
	settingMap := make(map[string]string)
	for _, v := range settingModel.ListAll() {
		settingMap[v.Key] = v.Val
	}
	webTitle := Cate.Title
	webKeywords := Cate.Keywords
	webDesc := Cate.Desc
	if Cate.Title == "" {
		webTitle = Cate.Name + "_" + settingMap["webTitle"]
	}
	if Cate.Keywords == "" {
		webKeywords = Cate.Name + "_" + settingMap["webTitle"]
	}
	if Cate.Desc == "" {
		webDesc = Cate.Name + "_" + settingMap["webTitle"]
	}
	settingMap["webTitle"] = webTitle
	settingMap["webKeywords"] = webKeywords
	settingMap["webDesc"] = webDesc
	data["setting"] = settingMap

	data["list"] = list
	data["pageNum"] = totalPages
	data["current"] = page
	data["totalCount"] = totalCount
	data["cid"] = cid
	data["Cate"] = Cate

	templatePath := "pc"
	if c.Ctx.IsMobile() {
		templatePath = "mobile"
	}

	return mvc.View{
		Name:   "www/" + templatePath + "/cate.html",
		Layout: "www/" + templatePath + "/shared/layoutFront.html",
		Data: iris.Map{
			"Title": "列表",
			"data":  data,
		},
	}
}

func (c *IndexController) GetDetailBy(id uint) mvc.View {
	Nav := model.Nav{}
	Category := model.Category{}
	info, _ := Nav.Info(id)
	ParentCate, _ := Category.ParentCate(int(info.CategoryId))
	_ = Nav.UpdateHitsNum(id)
	data := c.CommonData()

	//重写title keyword desc
	settingModel := model.Setting{}
	settingMap := make(map[string]string)
	for _, v := range settingModel.ListAll() {
		settingMap[v.Key] = v.Val
	}
	settingMap["webTitle"] = info.Title
	settingMap["webKeywords"] = info.Keywords
	settingMap["webDesc"] = info.Desc
	data["setting"] = settingMap

	data["info"] = info
	data["ParentCate"] = ParentCate

	templatePath := "pc"
	if c.Ctx.IsMobile() {
		templatePath = "mobile"
	}

	return mvc.View{
		Name:   "www/" + templatePath + "/detail.html",
		Layout: "www/" + templatePath + "/shared/layoutFront.html",
		Data: iris.Map{
			"Title": "详情",
			"data":  data,
		},
	}
}

func (c *IndexController) GetSearch1() mvc.View {
	word := c.Ctx.URLParamDefault("keyword", "")
	page, err := strconv.Atoi(c.Ctx.URLParam("page"))
	if err != nil || page < 1 {
		page = 1
	}
	search := make(map[string]string)
	search["title"] = word

	Nav := model.Nav{}
	list, totalCount, totalPages := Nav.List(page, search)
	//系统设置
	settingModel := model.Setting{}
	settingMap := make(map[string]string)
	for _, v := range settingModel.ListAll() {
		settingMap[v.Key] = v.Val
	}

	settingMap["webTitle"] = word
	var newList []model.Nav
	blackList := settingMap["searchBlackList"]
	if blackList != "" {
		blackListSlice := strings.Split(blackList, ",")
		for _, v := range list {
			flag := false
			for _, bv := range blackListSlice {
				if !strings.Contains(v.Title, bv) && !strings.Contains(v.Desc, bv) {
					flag = true
				}
			}
			if flag == true {
				newList = append(newList, v)
			}
		}
	}
	pages := make(map[string]interface{})
	pages["pageNum"] = totalPages
	pages["current"] = page
	pages["totalCount"] = totalCount

	templatePath := "pc"
	if c.Ctx.IsMobile() {
		templatePath = "mobile"
	}

	return mvc.View{
		Name:   "www/" + templatePath + "/search.html",
		Layout: "www/" + templatePath + "/shared/layoutSearch.html",
		Data: iris.Map{
			"keyword":    word,
			"SearchType": 1,
			"list":       list,
			"setting":    settingMap,
			"pages":      pages,
		},
	}
}

func (c *IndexController) GetSearch2() mvc.View {
	word := c.Ctx.URLParamDefault("keyword", "")
	page, err := strconv.Atoi(c.Ctx.URLParam("page"))
	if err != nil || page < 1 {
		page = 1
	}
	pageSize := config.GetInt("pagination.SearchPageSize")
	opts := &sphinx.Options{
		Host:    "localhost",
		Port:    9312,
		Timeout: 5000,
	}
	spClient := sphinx.NewClient(opts)
	// 查询
	res, _ := spClient.SetMatchMode(sphinx.SPH_MATCH_ALL).SetLimits((page-1)*pageSize, pageSize, 1000, 0).SetSortMode(sphinx.SPH_SORT_RELEVANCE, "").Query(word, "content", "ALL Query()")

	list := []model.Nav{}
	if res.Matches != nil && len(res.Matches) > 0 {
		ids := []string{}
		for _, match := range res.Matches {
			ids = append(ids, strconv.Itoa(int(match.DocId)))
		}
		Nav := model.Nav{}
		list = Nav.SearchList(ids)
	}

	//系统设置
	settingModel := model.Setting{}
	settingMap := make(map[string]string)
	for _, v := range settingModel.ListAll() {
		settingMap[v.Key] = v.Val
	}
	settingMap["webTitle"] = word
	newList := []model.Nav{}
	blackList := settingMap["searchBlackList"]
	if blackList != "" {
		blackListSlice := strings.Split(blackList, ",")
		for _, v := range list {
			flag := false
			for _, bv := range blackListSlice {
				if !strings.Contains(v.Title, bv) && !strings.Contains(v.Desc, bv) {
					flag = true
				}
			}
			if flag == true {
				newList = append(newList, v)
			}
		}
	}

	pages := make(map[string]interface{})
	pages["pageNum"] = math.Ceil(float64(res.TotalFound / pageSize))
	pages["current"] = page
	pages["totalCount"] = res.TotalFound

	templatePath := "pc"
	if c.Ctx.IsMobile() {
		templatePath = "mobile"
	}

	return mvc.View{
		Name:   "www/" + templatePath + "/search.html",
		Layout: "www/" + templatePath + "/shared/layoutSearch.html",
		Data: iris.Map{
			"SearchType": 2,
			"keyword":    word,
			"list":       newList,
			"setting":    settingMap,
			"pages":      pages,
		},
	}
}

func (c *IndexController) GetSitemap() {
	cacheKey := "GetSitemap"
	if v, rs := libs.GetCache(cacheKey); rs {
		_, _ = c.Ctx.XML(v)
		return
	}
	Nav := model.Nav{}
	_, _, totalPages := Nav.ListSiteMap(1)
	type SiteUrlXml struct {
		Url  string `xml:"loc"`
		Last string `xml:"lastmod"`
	}

	type SiteListXml struct {
		List []SiteUrlXml `xml:"sitemap"`
	}

	host := c.Ctx.Host()
	xml := SiteListXml{}
	for i := 1; i <= totalPages; i++ {
		xmlList := SiteUrlXml{
			Url:  host + "/sitemap/list/" + strconv.Itoa(i),
			Last: time.Now().Format("2006-01-02 15:04:05"),
		}
		xml.List = append(xml.List, xmlList)
	}
	setting := model.Setting{}
	libs.SetCacheDefault(cacheKey, xml, time.Duration(setting.CacheTime())*time.Second)
	_, _ = c.Ctx.XML(xml)
}

func (c *IndexController) GetSitemapListBy(page int) {
	cacheKey := "SitemapList" + strconv.Itoa(page)
	if v, rs := libs.GetCache(cacheKey); rs {
		_, _ = c.Ctx.XML(v)
		return
	}

	Nav := model.Nav{}
	list, _, _ := Nav.ListSiteMap(page)
	type SiteUrlXml struct {
		Url        string `xml:"loc"`
		Last       string `xml:"lastmod"`
		Changefreq string `xml:"changefreq"`
	}

	type SiteListXml struct {
		List []SiteUrlXml `xml:"url"`
	}

	host := c.Ctx.Host()
	xml := SiteListXml{}
	for _, v := range list {
		xmlList := SiteUrlXml{
			Url:        host + "/detail/" + strconv.Itoa(int(v.ID)),
			Last:       v.UpdatedAt.Format("2006-01-02 15:04:05"),
			Changefreq: "weekly",
		}
		xml.List = append(xml.List, xmlList)
	}
	setting := model.Setting{}
	libs.SetCacheDefault(cacheKey, xml, time.Duration(setting.CacheTime())*time.Second)
	_, _ = c.Ctx.XML(xml)
}

//获取验证码
func (c *IndexController) GetCaptcha() template.URL {
	CaptchaKey, CaptchaValue := libs.CodeCaptchaCreate("Digit")
	c.Session.Set("CaptchaKey", CaptchaKey)
	return template.URL(CaptchaValue)
}
